use super::{FileHandle, MessageButtons, MessageDialogResult, MessageLevel};
pub use rfd::{AsyncFileDialog, AsyncMessageDialog};
use std::path::PathBuf;
/// # 异步打开目录folder
/// ```rust
///  e_utils::dialog::a_sync::file().await
/// ```
pub async fn folder() -> Option<PathBuf> {
  AsyncFileDialog::new()
    .pick_folder()
    .await
    .map(|f| f.path().to_owned())
}
/// # 异步打开文件
/// ```rust
///  e_utils::dialog::a_sync::file().await
/// ```
pub async fn file() -> Option<PathBuf> {
  AsyncFileDialog::new()
    .pick_file()
    .await
    .map(|f| f.path().to_owned())
}
/// # 异步打开多个文件
/// ```rust
///  e_utils::dialog::a_sync::files().await
/// ```
pub async fn files() -> Option<Vec<PathBuf>> {
  AsyncFileDialog::new().pick_files().await.map(paths)
}
/// # 异步打开多个目录
/// ```rust
///  e_utils::dialog::a_sync::folders().await
/// ```
pub async fn folders() -> Option<Vec<PathBuf>> {
  AsyncFileDialog::new().pick_folders().await.map(paths)
}
/// # 异步创建文件
/// ```rust
///  e_utils::dialog::a_sync::create_file("newfile.txt").await
/// ```
pub async fn create_file(filename: impl Into<String>) -> Option<PathBuf> {
  AsyncFileDialog::new()
    .set_file_name(filename)
    .save_file()
    .await
    .map(|handle| handle.path().to_owned())
}
/// # Ok
/// ```rust
///  e_utils::dialog::a_sync::ok("Title","test").await
/// ```
pub async fn ok(title: &str, msg: impl Into<String>) {
  custom_one(title, msg, "OK").await
}
/// # 确认
/// ```rust
///  e_utils::dialog::a_sync::ok_zh("Title","test").await
/// ```
pub async fn ok_zh(title: &str, msg: impl Into<String>) {
  custom_one(title, msg, "确认").await
}
/// # Yes No
/// ```rust
///  e_utils::dialog::a_sync::yesno_zh("Title","test").await
/// ```
pub async fn yesno_zh(title: &str, msg: impl Into<String>) -> bool {
  custom_tow(title, msg, "同意", "拒绝").await
}
/// # Yes NO
/// ```rust
///  e_utils::dialog::a_sync::yesno("Title","test").await
/// ```
pub async fn yesno(title: &str, msg: impl Into<String>) -> bool {
  custom_tow(title, msg, "YES", "NO").await
}
/// # Info
/// ```rust
///  e_utils::dialog::a_sync::info("Title","test").await
/// ```
pub async fn info(title: &str, msg: impl Into<String>) {
  show(title, msg, MessageLevel::Info).show().await;
}
/// # Error
/// ```rust
///  e_utils::dialog::a_sync::error("Title","test").await
/// ```
pub async fn error(title: &str, msg: impl Into<String>) {
  show(title, msg, MessageLevel::Error).show().await;
}
/// # Warn
/// ```rust
///  e_utils::dialog::a_sync::warn("Title","test").await
/// ```
pub async fn warn(title: &str, msg: impl Into<String>) {
  show(title, msg, MessageLevel::Warning).show().await;
}
#[inline]
async fn custom_tow(
  title: &str,
  msg: impl Into<String>,
  custom1: impl Into<String>,
  custom2: impl Into<String>,
) -> bool {
  let dialog = show(title, msg, MessageLevel::Info)
    .set_buttons(MessageButtons::OkCancelCustom(
      custom1.into(),
      custom2.into(),
    ))
    .show()
    .await;
  if let MessageDialogResult::Ok = dialog {
    true
  } else {
    false
  }
}
#[inline]
async fn custom_one(title: &str, msg: impl Into<String>, custom: impl Into<String>) {
  show(title, msg, MessageLevel::Info)
    .set_buttons(MessageButtons::OkCustom(custom.into()))
    .show()
    .await;
}
#[inline]
fn show(title: &str, msg: impl Into<String>, msg_type: MessageLevel) -> AsyncMessageDialog {
  AsyncMessageDialog::new()
    .set_title(title)
    .set_description(msg)
    .set_level(msg_type)
}

fn paths(handles: Vec<FileHandle>) -> Vec<PathBuf> {
  handles.into_iter().map(|d| d.path().to_owned()).collect()
}

#[cfg(test)]
mod test {
  use crate::dialog::a_sync::*;
  #[tokio::test]
  async fn test_async_custom_tow() {
    assert_eq!(custom_tow("测试", "YES NO", "同意", "拒绝").await, true)
  }
  #[tokio::test]
  async fn test_async_custom_one() {
    assert_eq!(custom_one("测试", "custom_one", "确认").await, ())
  }
  #[tokio::test]
  async fn test_async_show() {
    assert_eq!(
      {
        show("测试", "show", MessageLevel::Info).show().await;
      },
      ()
    )
  }
  #[tokio::test]
  async fn test_async_folder() {
    assert!(folder().await.is_some())
  }

  #[tokio::test]
  async fn test_async_folders() {
    assert!(folders().await.is_some())
  }

  #[tokio::test]
  async fn test_async_files() {
    assert!(files().await.is_some())
  }
  #[tokio::test]
  async fn test_async_file() {
    assert!(file().await.is_some())
  }
  #[tokio::test]
  async fn test_async_create_file() {
    assert!(create_file("test.txt").await.is_some())
  }
}
